/*
 * @Author: lokei
 * @Date: 2023-07-05 21:28:26
 * @LastEditors: lokei
 * @LastEditTime: 2023-07-06 13:08:10
 * @Description: 
 */
package cn.lokei.task.service.iot.cabinet;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.springframework.data.redis.connection.stream.MapRecord;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service("cabinetService")
public class CabinetService {
    public void openBox(MapRecord<String, String, String> record) {
        String cabinetId = record.getValue().get("cabinetId");
        String appKey = record.getValue().get("appKey");
        String boxNo = record.getValue().get("boxNo");
        String appSecret = record.getValue().get("appSecret");

        SortedMap<String, Object> params = new TreeMap<>();
        params.put("timeStamp", (new Date().getTime()));
        params.put("cabinetId", cabinetId);
        params.put("appKey", appKey);
        params.put("boxNo", boxNo);

        String sb = new String("");
        for (String s : params.keySet()) {
            if (!sb.equals("")) {
                sb = (sb + "&" + s + "=" + params.get(s));
            } else {
                sb = (s + "=" + params.get(s));
            }
        }
        sb = sb + appSecret;
        sb = MD5(sb);
        params.put("sign", sb);

        HttpResponse http = HttpUtil.createPost("https://open.qianmingyun.com/webapi/apiService/v1/s1/openOneBox")
                .contentType("application/json")
                .body(JSONUtil.toJsonStr(params)).execute();
        int status = http.getStatus();
        if (status == 200) {
            String body = http.body();
            JSONObject result_json = (JSONObject) JSON.parse(body);
            if(result_json.getString("code").equals("200")) {

            } else {
                log.info("开箱失败，code：" + result_json.getString("code") + "，message：" + result_json.getString("message"));
            }
        } else {
            log.info("开箱失败，cabinetId：" + cabinetId + "，boxNo：" + boxNo);
        }
    }

    private static String MD5(String sourceStr) {
        String result = "";

        try {
            MessageDigest md = null;
            md = MessageDigest.getInstance("MD5");
            md.update(sourceStr.getBytes());
            byte b[] = md.digest();
            int j;
            StringBuilder buf = new StringBuilder("");
            for (int i = 0; i < b.length; i++) {
                j = b[i];
                if (j < 0)
                    j += 256;

                if (j < 16)
                    buf.append("0");

                buf.append(Integer.toHexString(j));
            }
            result = buf.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * Description:MD5工具生成token
     * 
     * @param value
     * @return
     */
    public String getMD5Value(String value) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] md5ValueByteArray = messageDigest.digest(value.getBytes());
            BigInteger bigInteger = new BigInteger(1, md5ValueByteArray);
            return bigInteger.toString(16).toUpperCase();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成签名
     * 
     * @param map
     * @return
     */
    public String getSignToken(Map<String, String> map, String appSecret) {
        String result = "";
        try {
            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(map.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
            Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {

                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造签名键值对的格式
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> item : infoIds) {
                if (item.getKey() != null || item.getKey() != "") {
                    String key = item.getKey();
                    String val = item.getValue();
                    if (!(val == "" || val == null)) {
                        sb.append(key + "=" + val + "&");
                    }
                }
            }
            result = sb.toString();
            result = result.substring(0, result.length() - 1) + appSecret;
            // 进行MD5加密
            result = getMD5Value(result);
        } catch (Exception e) {
            return null;
        }
        return result;
    }
}
